/**
 * Created by TamTT on 1/13/14.
 * FPT University - Da Nang
 * Capstone project - group 3
 * Jornee
 */
module.exports.controller = function (app, jwt, secret, db, authentication, util, async, log, colors, s3Client) {
	var fs = require('fs');
	var multiparty = require('multiparty');
	var crypto = require('crypto');
	var mongojs = require('mongojs');
	var graphicsmagick = require('gm');
	var gm = graphicsmagick.subClass({
		imageMagick: true
	});

	/**
	 * New entry - ThanhND
	 */
	app.post('/create_entry', function (req, res) {
		if (app.is_deploy) {
			var form = new multiparty.Form();
		} else {
			var form = new multiparty.Form({
				uploadDir: "./users_data"
			});
		}

		form.on('error', function (err) {
			if (err) {
				log.error('Create entry - error with %s'.red, err);
				console.log("Upload with error: " + err);
			}
			res.send({
				authen_status: 'ok',
				status: 'error'
			});
		});

		form.on('part', function (part) {
			var type = part.headers['content-type'];
			if (type) {
				type = type.split('/');
				type = type[1];
				if (type != 'jpeg' && type != 'png') {
					this.emit('error');
				}
			}
		});

		form.parse(req, function (err, fields, files) {
			if (err) {
				log.error('Create entry - error with %s'.red, err);
				res.send({
					authen_status: 'ok',
					status: 'error'
				});
			}
			if (!files && !fields) {
				log.warning('Create entry - No files and fields'.yellow);
				res.send({
					authen_status: 'ok',
					status: 'fail'
				});
			}
			var request = {};
			request.body = {};
			if (files && files.upload) {
				var file = files.upload[0];
				var type = file.headers['content-type'];
				type = type.split('/');
				type = type[1];
				if (type == 'jpeg') {
					type = 'jpg';
				}
				request.body.token = fields.token[0];
				authentication(request, function (result) {
					if (result.loginStatus == 'error') {
						res.send({
							authen_status: 'error'
						});
					} else if (result.loginStatus == 'false') {
						res.send({
							authen_status: 'fail'
						});
					} else if (result.loginStatus == 'true') {
						/**
						 * Code begin
						 */
						//Username: result.login_user
						var my_id = result.login_user;
						var path = './users_data/images/';
						var algorithm = 'aes256'; // supported by OpenSSL
						var info = {
							date: new Date()
						};
						var cipher = crypto.createCipher(algorithm, secret);
						var filename = cipher.update(my_id, 'utf8', 'hex') + cipher.final('hex') + "_" + jwt.encode(info, secret);

						if (app.is_deploy) { //In deploy environment
							var headers = {
								'x-amz-acl': 'public-read'
							};
							headers['Content-Length'] = files.upload[0].size;
//							s3Client.putFile(file.path, '/images/original/' + filename + '.' + type, function (err, s3Response) {
//								if (err) throw err;
//							});
							//Resize
							var img = gm(file.path);
							img.size(function (err, size) {
								if (err) throw err;
								if (!err) {
									if (size.width >= size.height) {
										img.resize(800)
											.write('/tmp/' + filename + '.' + type, function (err) {
											if (err) {
												log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
											} else {
												console.log("Resize large - Ok".blue);
											}
											s3Client.putFile('/tmp/' + filename + '.' + type, '/images/large/' + filename + '.' + type, function (err, s3Response) {
												if (err) {
													log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
													throw err;
												}
												else {
													console.log("Upload large - Ok - Status %s".blue, util.inspect(s3Response.statusCode));
												}
											});
										});
										img.resize(666)
											.write('/tmp/' + filename + '.' + type, function (err) {
												if (err) {
													log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
												} else {
													console.log("Resize medium - Ok".blue);
												}
											s3Client.putFile('/tmp/' + filename + '.' + type, '/images/medium/' + filename + '.' + type, function (err, s3Response) {
												if (err) {
													log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
													throw err;
												}
												else {
													console.log("Upload medium - Ok - Status %s".blue, util.inspect(s3Response.statusCode));
												}
											});
										});
										img.resize(500)
											.write('/tmp/' + filename + '.' + type, function (err) {
											if (err) {
												log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
											} else {
												console.log("Resize small - Ok".blue);
											}
											s3Client.putFile('/tmp/' + filename + '.' + type, '/images/small/' + filename + '.' + type, function (err, s3Response) {
												if (err) {
													log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
													throw err;
												} else {
													console.log("Upload small - Ok - Status %s".blue, util.inspect(s3Response.statusCode));
												}
											});
										});
										img.resize(206)
											.write('/tmp/' + filename + '.' + type, function (err) {
											if (err) {
												log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
											} else {
												console.log("Resize thumbnail - Ok".blue);
											}
											s3Client.putFile('/tmp/' + filename + '.' + type, '/images/thumbnail/' + filename + '.' + type, function (err, s3Response) {
												if (err) {
													log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
													throw err;
												} else {
													console.log("Upload thumbnail - Ok - Status %s".blue, util.inspect(s3Response.statusCode));
												}
											});
										});
									} else {
										img.resize(null, 800)
											.write('/tmp/' + filename + '.' + type, function (err) {
												if (err) {
													log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
												} else {
													console.log("Resize large - Ok".blue);
												}
												s3Client.putFile('/tmp/' + filename + '.' + type, '/images/large/' + filename + '.' + type, function (err, s3Response) {
													if (err) {
														log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
														throw err;
													}
													else {
														console.log("Upload large - Ok - Status %s".blue, util.inspect(s3Response.statusCode));
													}
											});
										});
										img.resize(null, 666)
											.write('/tmp/' + filename + '.' + type, function (err) {
											if (err) {
												log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
											} else {
												console.log("Resize medium - Ok".blue);
											}
											s3Client.putFile('/tmp/' + filename + '.' + type, '/images/medium/' + filename + '.' + type, function (err, s3Response) {
												if (err) {
													log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
													throw err;
												} else {
													console.log("Upload medium - Ok - Status %s".blue, util.inspect(s3Response.statusCode));
												}
											});
										});
										img.resize(null, 500)
											.write('/tmp/' + filename + '.' + type, function (err) {
											if (err) {
												log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
											} else {
												console.log("Resize small - Ok".blue);
											}
											s3Client.putFile('/tmp/' + filename + '.' + type, '/images/small/' + filename + '.' + type, function (err, s3Response) {
												if (err) {
													log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
													throw err;
												} else {
													console.log("Upload small - Ok - Status %s".blue, util.inspect(s3Response.statusCode));
												}
											});
										});
										img.resize(null, 206)
											.write('/tmp/' + filename + '.' + type, function (err) {
											if (err) {
												log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
											} else {
												console.log("Resize thumbnail - Ok".blue);
											}
											s3Client.putFile('/tmp/' + filename + '.' + type, '/images/thumbnail/' + filename + '.' + type, function (err, s3Response) {
												if (err) {
													log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
													throw err;
												} else {
													console.log("Upload thumbnail - Ok - Status %s".blue, util.inspect(s3Response.statusCode));
												}
											});
										});
									}
								}
							});
						} else { //Not in deploy environment
							fs.renameSync('./' + file.path, path + 'original/' + filename + '.' + type);
							//Resize
							var img = gm(path + 'original/' + filename + '.' + type);
							img.size(function (err, size) {
								if (err) throw err;
								if (!err) {
									if (size.width >= size.height) {
										img.resize(800);
										img.write('./users_data/images/large/' + filename + '.' + type, function (err) {
											if (err) {
												log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
												res.send({
													authen_status: 'ok',
													status: 'error'
												});
											}
										});
										img.resize(666);
										img.write('./users_data/images/medium/' + filename + '.' + type, function (err) {
											if (err) {
												log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
												res.send({
													authen_status: 'ok',
													status: 'error'
												});
											}
										});
										img.resize(500);
										img.write('./users_data/images/small/' + filename + '.' + type, function (err) {
											if (err) {
												log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
												res.send({
													authen_status: 'ok',
													status: 'error'
												});
											}
										});
										img.resize(206);
										img.write('./users_data/images/thumbnail/' + filename + '.' + type, function (err) {
											if (err) {
												log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
												res.send({
													authen_status: 'ok',
													status: 'error'
												});
											}
										});
									} else {
										img.resize(null, 800);
										img.write('./users_data/images/large/' + filename + '.' + type, function (err) {
											if (err) {
												log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
												res.send({
													authen_status: 'ok',
													status: 'error'
												});
											}
										});
										img.resize(null, 666);
										img.write('./users_data/images/medium/' + filename + '.' + type, function (err) {
											if (err) {
												log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
												res.send({
													authen_status: 'ok',
													status: 'error'
												});
											}
										});
										img.resize(null, 500);
										img.write('./users_data/images/small/' + filename + '.' + type, function (err) {
											if (err) {
												log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
												res.send({
													authen_status: 'ok',
													status: 'error'
												});
											}
										});
										img.resize(null, 206);
										img.write('./users_data/images/thumbnail/' + filename + '.' + type, function (err) {
											if (err) {
												log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
												res.send({
													authen_status: 'ok',
													status: 'error'
												});
											}
										});
									}
								}
							});
						}
						var coordinate = "";
						if (fields.coordinate) {
							coordinate = eval(fields.coordinate[0]);
						}

						var place_name = "";
						if (fields.place_name) {
							place_name = fields.place_name[0];
						}
						var text = "";
						if (fields.text) {
							text = fields.text[0];
						}
						var create_date = fields.create_date[0];
						var country = "";
						if (fields.country) {
							country = fields.country[0].fromVi();
						}
						var administrative_area_level_1 = "";
						if (fields.administrative_area_level_1) {
							administrative_area_level_1 = fields.administrative_area_level_1[0].fromVi();
						}
						var administrative_area_level_2 = "";
						if (fields.administrative_area_level_2) {
							administrative_area_level_2 = fields.administrative_area_level_2[0].fromVi();
						}
						var locality = "";
						if (fields.locality) {
							locality = fields.locality[0].fromVi();
						}
						var sublocality = "";
						if (fields.sublocality) {
							sublocality = fields.sublocality[0].fromVi();
						}
						var route = "";
						if (fields.route) {
							route = fields.route[0].fromVi();
						}
						var street_number = "";
						if (fields.street_number) {
							street_number = fields.street_number[0].fromVi();
						}
						var modified_date = "";
						if (fields.modified_date) {
							modified_date = fields.modified_date[0];
						}
						var entry_type = fields.type[0];
						var journey_id = "";
						if (fields.journey_id) {
							journey_id = eval(fields.journey_id[0]);
						}
						var query_array = [];
						journey_id.forEach(function (j_id) {
							query_array.push(mongojs.ObjectId(j_id));
						});
						db.place.findOne({
							country: country,
							administrative_area_level1: administrative_area_level_1,
							administrative_area_level2: administrative_area_level_2,
							locality: locality,
							sublocality: sublocality,
							route: route,
							street_number: street_number
						}, function (err, doc) {
							if (err) {
								log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
								res.send({
									authen_status: 'ok',
									status: 'error'
								});
							}
							if (doc) {
								if (fields.entry_id && fields.entry_id[0] != '') {
									db.entry.update({
										_id: mongojs.ObjectId(fields.entry_id[0])
									}, {
										$set: {
											type: entry_type,
											username: result.login_user,
											coordinate: coordinate,
											place_id: doc._id,
											place_name: place_name,
											create_date: create_date,
											text: text,
											path: filename + '.' + type,
											modified_date: modified_date
										}
									}, function (err) {
										if (err) {
											log.error('Update entry - User %s - error with %s'.red, result.login_user, err);
											res.send({
												authen_status: 'ok',
												status: 'error'
											});
										} else {
											log.info('Update entry - User %s - OK'.blue, result.login_user);
											res.send({
												authen_status: 'ok',
												status: 'ok'
											});
										}
									})
								} else {
									db.entry.insert({
										type: entry_type,
										username: result.login_user,
										coordinate: coordinate,
										place_id: doc._id,
										place_name: place_name,
										text: text,
										path: filename + '.' + type,
										iplace_id: "",
										create_date: create_date,
										modified_date: ""
									}, function (err, entry) {
										if (err) {
											log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
											res.send({
												authen_status: 'ok',
												status: 'error'
											});
										} else {
											db.journey.update({
												_id: {
													$in: query_array
												}
											}, {
												$addToSet: {
													entries: entry._id
												}
											}, function (err) {
												if (err) {
													log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
													res.send({
														authen_status: 'ok',
														status: 'error'
													});
												} else {
													log.info('Create entry - User %s - OK'.blue, result.login_user);
													res.send({
														authen_status: 'ok',
														status: 'ok',
														entry_id: entry._id
													});
												}
											})
										}
									})
								}
							} else {
								db.place.insert({
									country: country,
									administrative_area_level1: administrative_area_level_1,
									administrative_area_level2: administrative_area_level_2,
									locality: locality,
									sublocality: sublocality,
									route: route,
									street_number: street_number
								}, function (err, doc) {
									if (err) {
										log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
										res.send({
											authen_status: 'ok',
											status: 'ok'
										});
									}
									if (!doc) {
										log.warning('Create entry - User %s - Insert fail'.yellow, result.login_user);
										res.send({
											authen_status: 'ok',
											status: 'fail'
										});
									} else {
										if (fields.entry_id && fields.entry_id[0] != '') {
											db.entry.update({
												_id: mongojs.ObjectId(fields.entry_id[0])
											}, {
												$set: {
													type: entry_type,
													username: result.login_user,
													coordinate: coordinate,
													place_id: doc._id,
													place_name: place_name,
													create_date: create_date,
													text: text,
													path: filename + '.' + type,
													modified_date: modified_date
												}
											}, function (err) {
												if (err) {
													log.error('Update entry - User %s - error with %s'.red, result.login_user, err);
													res.send({
														authen_status: 'ok',
														status: 'error'
													});
												} else {
													log.info('Update entry - User %s - OK'.blue, result.login_user);
													res.send({
														authen_status: 'ok',
														status: 'ok'
													});
												}
											})
										} else {
											db.entry.insert({
												type: entry_type,
												username: result.login_user,
												coordinate: coordinate,
												place_id: doc._id,
												place_name: place_name,
												text: text,
												path: filename + '.' + type,
												iplace_id: "",
												create_date: create_date,
												modified_date: ""
											}, function (err, entry) {
												if (err) {
													log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
													res.send({
														authen_status: 'ok',
														status: 'error'
													});
												} else {
													db.journey.update({
														_id: {
															$in: query_array
														}
													}, {
														$addToSet: {
															entries: entry._id
														}
													}, function (err) {
														if (err) {
															log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
															res.send({
																authen_status: 'ok',
																status: 'error'
															});
														} else {
															log.info('Create entry - User %s - OK'.blue, result.login_user);
															res.send({
																authen_status: 'ok',
																status: 'ok',
																entry_id: entry._id
															});
														}
													})
												}
											})
										}
									}
								})
							}
						});
					}
				});
			} else {
				if (fields) {
					request.body.token = fields.token[0];
					authentication(request, function (result) {
						if (result.loginStatus == 'error') {
							fs.unlink(file.path);
							res.send({
								authen_status: 'error'
							});
						} else if (result.loginStatus == 'false') {
							fs.unlink(file.path);
							res.send({
								authen_status: 'fail'
							});
						} else if (result.loginStatus == 'true') {
							var coordinate = "";
							if (fields.coordinate) {
								coordinate = eval(fields.coordinate[0]);
							}
							var place_name = "";
							if (fields.place_name) {
								place_name = fields.place_name[0];
							}
							var text = "";
							if (fields.text) {
								text = fields.text[0];
							}
							var create_date = fields.create_date[0];
							var country = "";
							if (fields.country) {
								country = fields.country[0].fromVi();
							}
							var administrative_area_level_1 = "";
							if (fields.administrative_area_level_1) {
								administrative_area_level_1 = fields.administrative_area_level_1[0].fromVi();
							}
							var administrative_area_level_2 = "";
							if (fields.administrative_area_level_2) {
								administrative_area_level_2 = fields.administrative_area_level_2[0].fromVi();
							}
							var locality = "";
							if (fields.locality) {
								locality = fields.locality[0].fromVi();
							}
							var sublocality = "";
							if (fields.sublocality) {
								sublocality = fields.sublocality[0].fromVi();
							}
							var route = "";
							if (fields.route) {
								route = fields.route[0].fromVi();
							}
							var street_number = "";
							if (fields.street_number) {
								street_number = fields.street_number[0].fromVi();
							}
							var entry_type = fields.type[0];
							var modified_date = "";
							if (fields.modified_date) {
								modified_date = fields.modified_date[0];
							}
							var journey_id = "";
							if (fields.journey_id) {
								journey_id = eval(fields.journey_id[0]);
							}
							var query_array = [];
							journey_id.forEach(function (j_id) {
								query_array.push(mongojs.ObjectId(j_id));
							});
							db.place.findOne({
								country: country,
								administrative_area_level1: administrative_area_level_1,
								administrative_area_level2: administrative_area_level_2,
								locality: locality,
								sublocality: sublocality,
								route: route,
								street_number: street_number
							}, function (err, doc) {
								if (err) {
									log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
									res.send({
										authen_status: 'ok',
										status: 'error'
									});
								}
								if (doc) {
									if (fields.entry_id && fields.entry_id[0] != '') {
										db.entry.update({
											_id: mongojs.ObjectId(fields.entry_id[0])
										}, {
											$set: {
												type: entry_type,
												username: result.login_user,
												coordinate: coordinate,
												place_id: doc._id,
												place_name: place_name,
												create_date: create_date,
												text: text,
												modified_date: modified_date
											}
										}, function (err) {
											if (err) {
												log.error('Update entry - User %s - error with %s'.red, result.login_user, err);
												res.send({
													authen_status: 'ok',
													status: 'error'
												});
											} else {
												log.info('Update entry - User %s - OK'.blue, result.login_user);
												res.send({
													authen_status: 'ok',
													status: 'ok'
												});
											}
										})
									} else {
										db.entry.insert({
											type: entry_type,
											coordinate: coordinate,
											place_id: doc._id,
											place_name: place_name,
											text: text,
											path: "",
											iplace_id: "",
											create_date: create_date,
											modified_date: ""
										}, function (err, entry) {
											if (err) {
												log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
												res.send({
													authen_status: 'ok',
													status: 'error'
												});
											} else {
												db.journey.update({
													_id: {
														$in: query_array
													}
												}, {
													$addToSet: {
														entries: entry._id
													}
												}, function (err) {
													if (err) {
														log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
														res.send({
															authen_status: 'ok',
															status: 'error'
														});
													} else {
														log.info('Create entry - User %s - OK'.blue, result.login_user);
														res.send({
															authen_status: 'ok',
															status: 'ok',
															entry_id: entry._id
														});
													}
												})
											}
										})
									}
								} else {
									db.place.insert({
										country: country,
										administrative_area_level1: administrative_area_level_1,
										administrative_area_level2: administrative_area_level_2,
										locality: locality,
										sublocality: sublocality,
										route: route,
										street_number: street_number
									}, function (err, doc) {
										if (err) {
											log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
											res.send({
												authen_status: 'ok',
												status: 'ok'
											});
										}
										if (!doc) {
											log.warning('Create entry - User %s - Insert fail'.yellow, result.login_user);
											res.send({
												authen_status: 'ok',
												status: 'fail'
											});
										} else {
											if (fields.entry_id && fields.entry_id[0] != '') {
												db.entry.update({
													_id: mongojs.ObjectId(fields.entry_id[0])
												}, {
													$set: {
														type: entry_type,
														username: result.login_user,
														coordinate: coordinate,
														place_id: doc._id,
														create_date: create_date,
														place_name: place_name,
														text: text,
														modified_date: modified_date
													}
												}, function (err) {
													if (err) {
														log.error('Update entry - User %s - error with %s'.red, result.login_user, err);
														res.send({
															authen_status: 'ok',
															status: 'error'
														});
													} else {
														log.info('Update entry - User %s - OK'.blue, result.login_user);
														res.send({
															authen_status: 'ok',
															status: 'ok'
														});
													}
												})
											} else {
												db.entry.insert({
													type: entry_type,
													username: result.login_user,
													coordinate: coordinate,
													place_id: doc._id,
													place_name: place_name,
													text: text,
													path: "",
													iplace_id: "",
													create_date: create_date,
													modified_date: ""
												}, function (err, entry) {
													if (err) {
														log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
														res.send({
															authen_status: 'ok',
															status: 'error'
														});
													} else {
														db.journey.update({
															_id: {
																$in: query_array
															}
														}, {
															$addToSet: {
																entries: entry._id
															}
														}, function (err) {
															if (err) {
																log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
																res.send({
																	authen_status: 'ok',
																	status: 'error'
																});
															} else {
																log.info('Create entry - User %s - OK'.blue, result.login_user);
																res.send({
																	authen_status: 'ok',
																	status: 'ok',
																	entry_id: entry._id
																});
															}
														})
													}
												})
											}
										}
									})
								}
							});
						}
					});
				} else {
					log.warning('Create entry - No fields'.yellow);
					res.send({
						authen_status: 'ok',
						status: 'fail'
					});
				}
			}
		});
	});

	/**
	 * Delete entry - ThanhND
	 */
	app.post('/delete_entry', function (req, res) {
		authentication(req, function (result) {
			if (result.loginStatus == 'error') {
				res.send({
					authen_status: 'error'
				});
			} else if (result.loginStatus == 'false') {
				res.send({
					authen_status: 'fail'
				});
			} else if (result.loginStatus == 'true') {
				/**
				 * Code begin
				 */
				var entry_id = req.body.entry_id;

				db.entry.remove({
					_id: mongojs.ObjectId(entry_id)
				}, function (err) {
					if (err) {
						log.error('Create entry - User %s - error with %s'.red, result.login_user, err);
						res.send({
							authen_status: 'ok',
							status: 'error'
						});
					} else {
						db.journey.update({
							entries: mongojs.ObjectId(entry_id)
						}, {
							$pull: {
								entries: mongojs.ObjectId(entry_id)
							}
						}, function (err) {
							if (err) {
								log.error('Delete entry - User %s - error with %s'.red, result.login_user, err);
								res.send({
									authen_status: 'ok',
									status: 'error'
								});
							} else {
								log.info('Delete entry - User %s - OK'.blue, result.login_user);
								res.send({
									authen_status: 'ok',
									status: 'ok'
								});
							}
						})
					}
				})
			}
		});
	});
};